#include <cassert>
#include <tuple>
#include <string>
namespace flyboy{
	class DateTime;
	//operation function
	const std::tuple<int, int, int> operator -(const DateTime& one, const DateTime& another);
	const DateTime operator+(const DateTime&, int);
	const DateTime operator+(int, const DateTime&);
	const DateTime operator-(const DateTime&, int);
	const DateTime operator-(int, const DateTime&);
	std::ostream& operator<<(std::ostream&, const DateTime&);
	const std::string FormatTuple(const std::tuple<int, int, int>&);

	class DateTime{
#		define Geter(type, fname, vname)	\
			type Get##fname() const{\
			return vname;	\
		}

	public:
		using data_type = size_t;
		enum class AdjustType : char{
			ADJUST_MIN = 0,
			ADJUST_YEAR = AdjustType::ADJUST_MIN,
			ADJUST_MONTH,
			ADJUST_DAY,
			ADJUST_MAX,
		};
		
		enum class WeekType{
			WEEK_MIN = 0,
			WEEK_MONDAY = WeekType::WEEK_MIN,
			WEEK_TUESDAY,
			WEEK_WEDNESDAY,
			WEEK_THURSDAY,
			WEEK_FRIDAY,
			WEEK_SATURDAY,
			WEEK_SUNDAY,
			WEEK_MAX,
		};

		enum class DateDiffType{
			DIFF_MIN = 0,
			DIFF_YEAR = DateDiffType::DIFF_MIN,
			DIFF_MONTH,
			DIFF_DAY,
			DIFF_MAX,
		};

		explicit DateTime(int year = 1991, int month = 03, int day = 03, WeekType week = WeekType::WEEK_SUNDAY);
		~DateTime();

		Geter(data_type, Year, year)
		Geter(data_type, Month, month)
		Geter(data_type, Day, day)
		Geter(WeekType, Week, week)
		void Adjust(AdjustType which, int delta);

#		undef Geter

		operator std::string() const;
	private:
		data_type year;
		data_type month;
		data_type day;
		WeekType week;
	};
	//size_t GetDiffVar(const std::tuple<int, int, int>&, const DateTime::DateDiffType&);
}